package com.zimmur.tools;

import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.google.common.base.Optional;
import com.zimmur.common.ConstData;
import com.zimmur.model.dto.UserDTO;
import com.zimmur.service.RedisCacheUtil;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Component
public class JwtTokenUtil {
	private static Logger log = LoggerFactory.getLogger(JwtTokenUtil.class);
	
	@Resource
	private RedisCacheUtil<String> redis;
	/**
	 * token过期时间 24H*7
	 */
	private static final long VALIDITY_TIME_MS = 7 * 24 * 60 * 60 * 1000;
	/**
	 * 签名密钥
	 */
//	@Value("${jwt.token.secret}")
	private String secret="zimmur2015";  
	
	@Value("${System.GuestId}")
	private String guessUserId;
	/**
	 * 验签
	 */
	public Optional<UserDTO> verifyToken(HttpServletRequest request) {
		final String token = request.getParameter(ConstData.USER_ACCESS_TOKEN);
		if (token != null && !token.isEmpty()) {
			final UserDTO user = parse(token.trim());
			if (user != null ) {
				if(user.getUserId().equals(guessUserId)){
					return Optional.of(user);
				}
					
				if(equelsWithRedis(token, user.getUserId())){
					return Optional.of(user);
				}
			}
		}
		return Optional.fromNullable(null);
	}

	private boolean equelsWithRedis(final String token, final String userId) {
		String redisToken = redis.getHashMap(ConstData.REDIS_USERLOGIN_PREFIX, userId);
		if (redisToken != null && !"".equals(redisToken)) {
			return redisToken.equals(token);
		}
		return false;
	}

	/**
	 * 从用户中创建一个jwt Token
	 *
	 * @param userDTO
	 *            用户
	 * @return token
	 */
	public String create(UserDTO userDTO) {
		return Jwts.builder()
				.setExpiration(new Date(System.currentTimeMillis() + VALIDITY_TIME_MS))
				.setSubject(userDTO.getUserName())
				.claim("id", userDTO.getUserId())
				.signWith(SignatureAlgorithm.HS256, secret).compact();
	}

	/**
	 * 从token中取出用户
	 */
	public UserDTO parse(String token) {
		try {
			Claims claims = Jwts.parser()
					.setSigningKey(secret)
					.parseClaimsJws(token)
					.getBody();
			UserDTO userDTO = new UserDTO();
			userDTO.setUserId(claims.get("id").toString());
			userDTO.setUserName(claims.getSubject());
			return userDTO;
		}catch(ExpiredJwtException e){
			//log.error("Parse Method ExpiredJwtException Error", e);
		}
		catch (Exception e) {
			log.error("Parse Method Error", e);
		}
		return null;
	}
	
	/**
	 * 根据Token返回用户ID
	 * @param token
	 * @return
	 */
	public long getUserId(String token){
		UserDTO userDTO = parse(token);
		if(userDTO != null){
			return Long.parseLong(userDTO.getUserId());
		}
		return 0;
	}
	
	public static void main(String[] args) {
		//create
		JwtTokenUtil jTokenUtil = new JwtTokenUtil();
		UserDTO userDTO = new UserDTO();
		userDTO.setUserId("123456");
		userDTO.setUserName("jacks");
		
		String token = jTokenUtil.create(userDTO);
		
		System.out.println("token->"+token);
		
		UserDTO parse = jTokenUtil.parse(token);
		System.out.println("token decode->" + parse);
	}
}
